<!-- title: '新建教案',
labelWidth: '100px',
isBetween: true, //false:搜索按钮布局  true:表单布局
formList: 动态表单,
callBack: () => diaSubmit, 提交回调函数=》返回表单值
serachFn:搜索按钮

-->
<template>
  <!-- <el-dialog destroy-on-close v-bind="$attrs" :title="option.title || '项目详情'" width="1000px"> -->
  <el-form
    ref="formDom"
    :model="formData"
    :label-width="props.option.labelWidth || '100px'"
    :label-position="props.option.position || 'right'"
    :rules="rules"
  >
    <div
      v-loading="props.option.formList.length == 0"
      class="row-box"
      :class="[
        { between: props.option.isBetween },
        { labelH5: props.option.labelH5 },
      ]"
    >
      <template
        v-for="(item, INDEX) in props.option.formList"
        :key="item.label"
      >
        <div
          v-if="!item.hidden"
          class="row-one"
          :style="{ width: item.width }"
          :class="[
            {
              rightMargin: item.rightMargin,
              uploadRow: item.type == 'upload',
            },
            { selectLine: item.innerClass },
            { uploadHeight: item.type == 'upload' },
          ]"
        >
          <el-form-item
            v-if="item.label"
            :label="item.label"
            :prop="item.field"
            :label-width="item.labelWidth"
          >
            <!-- <div class="title-box" v-if="item.type == 'title'">
              <titleLine :title="item.title" />
            </div> -->

            <el-input
              v-if="item.type == 'input' && item.isNumber"
              v-model="formData[`${item.field}`]"
              :style="{
                width: item.inputWidth || '100%',
              }"
              :placeholder="item.placeholder || '请输入'"
              :disabled="item.disabled"
              :type="item.inputType || 'text'"
              :parser="item.parser"
              :formatter="item.formatter"
              :maxlength="item.maxlength"
              :show-word-limit="item.maxlength ? true : false"
              :autosize="item.autosize"
              resize="none"
              @change="item.change"
              @input="(value) => handleNumberInput(value, item.field)"
            />
            <el-input
              v-if="item.type == 'input' && !item.isNumber"
              v-model="formData[`${item.field}`]"
              :style="{
                width: item.inputWidth || '100%',
              }"
              :placeholder="item.placeholder || '请输入'"
              :disabled="item.disabled"
              :type="item.inputType || 'text'"
              :parser="item.parser"
              :formatter="item.formatter"
              :maxlength="item.maxlength"
              :show-word-limit="item.maxlength ? true : false"
              :autosize="item.autosize"
              resize="none"
              @change="item.change"
            />
            <el-tree-select
              v-if="item.type == 'treeSelect'"
              v-model="formData[`${item.field}`]"
              :data="item.chooseList"
              :render-after-expand="false"
              :style="{
                width: item.inputWidth || '100%',
              }"
              :disabled="item.disabled"
              :check-strictly="item.checkStrictly || false"
            />
            <!-- :lazy="true"
              :props="item.props || {}" -->

            <el-select
              v-if="item.type == 'select'"
              v-model="formData[`${item.field}`]"
              :multiple="item.multiple"
              :placeholder="item.placeholder || '请选择'"
              :style="{
                width: item.inputWidth || '100%',
              }"
              :disabled="item.disabled"
              :filterable="item.filterable"
              :remote="item.remote"
              :remote-method="item.remoteMethod"
              collapse-tags-tooltip
              @change="item.change"
              @remove-tag="item.removeTag"
              :loading="item.loading"
            >
              <el-option
                v-for="selectData in item.chooseList || []"
                :key="selectData[item.chooseListField?.[1] || 'value']"
                :label="selectData[item.chooseListField?.[0] || 'label']"
                :value="selectData[item.chooseListField?.[1] || 'value']"
                :disabled="selectData.noSelect"
              />
            </el-select>
            <!-- 固定字段-此处写死,加字段需要后端同步 -->
            <el-radio-group
              v-if="item.type == 'radio'"
              v-model="formData[`${item.field}`]"
              class="ml-4"
              :disabled="item.disabled"
              @change="item.change"
            >
              <el-radio
                v-for="(selectData, $index) in item.chooseList || []"
                :key="$index"
                :label="selectData[item.chooseListField?.[0] || 'value']"
                size="large"
                >{{
                  selectData[item.chooseListField?.[1] || 'label']
                }}</el-radio
              >
            </el-radio-group>
            <el-checkbox-group
              v-if="item.type == 'checkbox'"
              v-model="formData[`${item.field}`]"
              :disabled="item.disabled"
            >
              <el-checkbox
                v-for="(check, $index) in item.chooseList"
                :key="$index"
                :label="check[item.chooseListField?.[0] || 'label']"
              >
                {{ check[item.chooseListField?.[1] || 'value'] }}
              </el-checkbox>
            </el-checkbox-group>
            <div v-if="item.type == 'date'">
              <el-date-picker
                v-model="formData[`${item.field}`]"
                :value-format="timeTypeFormat[item.check_type] || 'YYYY-MM-DD'"
                :type="timeType[item.check_type] || 'date'"
                placeholder="请选择"
                :disabled="item.disabled"
                :disabled-date="item.disableFutureDate"
              />
            </div>

            <div v-if="item.type == 'upload'" class="upload-width">
              <nav v-if="!item.disabled" class="up-accept">
                可上传{{ item.accept }}
                <span
                  >最多上传 {{ item.limit }}
                  {{ item.uploadType == 'img' ? '张' : '个' }}</span
                >
              </nav>
              <div v-if="formData[`${item.field}_loading`]" class="progress">
                <el-progress
                  class="progress-num"
                  :percentage="item.percent"
                  color="#409eff"
                />
                <!-- <el-button link @click="abortUpload(item)">取消</el-button> -->
              </div>
              <!-- :limit="item.limit || 1" -->
              <el-upload
                ref="uploadDom"
                v-model="formData[`${item.field}`]"
                v-loading="formData[`${item.field}_loading`]"
                class="annexUpLoad"
                :show-file-list="false"
                :accept="item.accept"
                action=""
                :disabled="item.disabled"
                :before-upload="
                  (file) => {
                    return beforeFileUpload(file, item);
                  }
                "
                :http-request="(request) => uploadFileInit(request, item)"
              >
                <main class="row2-line">
                  <!-- 上传按钮  disable 或者超出最大上传数隐藏 -->
                  <div v-if="!item.disabled" class="download-btn write">
                    <el-icon class="el-icon--right">
                      <Upload />
                    </el-icon>
                    <span>{{ item.title || '上传' }} </span>
                  </div>
                  <div
                    v-for="(uploadItem, upIndex) in formData[`${item.field}`]"
                    :key="upIndex"
                    class="upload-box self-box"
                    :class="[
                      { h5UploadBoc: props.option.isH5 },
                      {
                        videoBox:
                          props.option.isH5 && item.uploadType == 'video',
                      },
                      { showList: item.showList },
                    ]"
                  >
                    <!-- 上传成功列表 -->

                    <div class="up-list-box">
                      <el-icon><Document /></el-icon>
                      <!-- <img class="file-icon" src="@/assets/upload/fileIcon.png" alt="" /> -->
                      <div class="up-name ell">
                        {{ uploadItem.name }}

                        <img
                          v-if="item.uploadType == 'img'"
                          :src="imgUrl + uploadItem.url"
                          width="100"
                          height="100"
                          alt=""
                        />
                      </div>

                      <span
                        v-if="
                          getSuffix(uploadItem) != 'zip' &&
                          getSuffix(uploadItem) != 'rar'
                        "
                        class="upload-btn-it"
                        @click.capture.stop="lookPic(uploadItem, item)"
                      >
                        查看</span
                      >
                      <span
                        v-if="
                          getSuffix(uploadItem) != 'zip' &&
                          getSuffix(uploadItem) != 'rar' &&
                          props.option.showEditFile
                        "
                        class="upload-btn-it"
                        @click.capture.stop="uploadClick(uploadItem, item)"
                        >编辑</span
                      >
                      <span
                        v-if="!props.option.downLoadHiddle"
                        class="upload-btn-it"
                        @click.capture.stop="
                          downloadFile(uploadItem.url, uploadItem.name)
                        "
                        >下载</span
                      >
                      <span
                        v-if="!item.disabled"
                        class="upload-btn-it del-btn"
                        @click.capture.stop="removeFile(item, upIndex)"
                        >删除</span
                      >
                    </div>
                  </div>
                </main>
              </el-upload>
            </div>
          </el-form-item>
        </div>
      </template>
      <footer v-if="props.option.showSreach" class="serach-btn">
        <el-button type="primary" @click="serachBtn">搜索</el-button>
        <el-button type="" @click="resetBtn">重置</el-button>
      </footer>
    </div>
  </el-form>
  <footer v-if="props.option.showSubmit" class="btn-list">
    <el-button type="" @click="closeDialog">取消</el-button>
    <el-button type="primary" :loading="subLoading" @click="submit">
      {{ props.option.submitName || '提交' }}</el-button
    >
  </footer>
</template>

<script setup lang="ts">
  import { ref, onMounted, reactive, useAttrs, computed, watch } from 'vue';
  import { useRouter } from 'vue-router';
  import { Upload, Document } from '@element-plus/icons-vue';
  import { ElMessage, ElMessageBox } from 'element-plus';
  // import { downloadFile } from "@/utils/util.js"
  import axios from 'axios';

  // 简单的下载文件函数
  const downloadFile = (url: string, filename: string) => {
    const link = document.createElement('a');
    link.href = url;
    link.download = filename;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  };

  const props = defineProps({
    option: {
      type: Object,
      default: () => {
        return {
          formList: [],
        };
      },
    },
    keyCount: {
      type: Number,
    },
  });
  const test = ref('');
  const emits = defineEmits(['submitFn', 'cancleFn', 'serachFn', 'resetFn']);
  const formData = ref({});
  const rules = reactive({});
  const router = useRouter();
  const state = reactive({});
  const attrs = useAttrs();
  const subLoading = ref(false);
  const timeType = {
    6: 'year',
    7: 'month',
    8: 'date',
    9: 'daterange',
  };

  const timeTypeFormat = {
    6: 'YYYY',
    7: 'YYYY-MM',
    8: 'YYYY-MM-DD',
    9: 'YYYY-MM-DD',
    '': 'YYYY-MM-DD',
  };
  watch(
    () => attrs.modelValue,
    (val) => {
      if (val) {
        console.log('init');
        inits();
      }
    }
  );
  watch(
    () => props.keyCount,
    (val) => {
      if (val) {
        console.log('keyCount');
        inits();
      }
    }
  );
  function uploadFileInit(e, item) {
    console.log(111, e.file);
    console.log(222, item);

    const { uploadType } = item;

    const fd = new FormData();
    fd.append('file', e.file);
    const rtoken = localStorage.getItem('rtoken');
    const token = localStorage.getItem('token');

    const isImg = uploadType == 'img';

    // uploadPicture({ fd })
    const upUrl = isImg ? '/admin/v1/upload/picture' : '/admin/v1/upload/file';
    axios({
      url: `/bapi${upUrl}`, //
      method: 'post',
      data: fd,
      headers: {
        'Authorization': token,
        'Refresh-Token': rtoken,
        'Content-Type': 'multipart/form-data',
      },
    }).then((res) => {
      const { data } = res.data;
      console.log('上传成功', res);
      formData.value[`${item.field}`] = [
        {
          name: e.file.name,
          url: res.data.url,
        },
      ];
      formData.value[`${item.field}_loading`] = false;
      delete formData.value[`${item.field}_loading`];
    });
  }
  function lookPic(uploadItem, item) {
    console.log(uploadItem, item);
    window.open(uploadItem.url);
  }
  function uploadEmpty(item) {
    if (item) {
      return item.length == 0;
    }
    return false;
  }
  function ResetFormDate() {
    // 清空表单值
    const keys = Object.keys(formData.value);
    keys.map((k) => {
      const item = formData.value[k];
      if (Array.isArray(item)) {
        formData.value[k] = [];
      } else {
        formData.value[k] = '';
      }
    });
  }
  function serachBtn() {
    console.log('formData.value', formData.value);
    const datas = JSON.parse(JSON.stringify(formData.value));
    emits('serachFn', datas);
  }
  function resetBtn() {
    // props.option.resetFn();
    ResetFormDate();

    emits('resetFn', {});
  }

  function selectChange(item) {
    item.change();
  }
  function closeDialog() {
    (attrs['onUpdate:modelValue'] as (boolean) => void)?.(false);
    emits('cancleFn', {});
  }
  const formDom: any = ref(null);
  function submit() {
    formDom.value.validate((v) => {
      console.log('sub', v);

      console.log(111, formData.value);
      // const { tab_type, callBack } = props.option;
      if (!v) return;
      subLoading.value = true;

      const loadingKey = Object.keys(formData.value).filter((item) => {
        // 删除loading 字段
        return item.indexOf('_loading') > -1;
      });

      loadingKey.map((k) => {
        delete formData.value[k];
        // if (k == 'tempDate') {

        // }
      });

      const reData = JSON.parse(JSON.stringify(formData.value));

      // if (callBack) {
      console.log('formData.value', reData);
      emits('submitFn', reData);

      setTimeout(() => {
        subLoading.value = false;
      }, 1000);

      // }
    });
  }

  const errorTips = {
    input: '请输入',
    select: '请选择',
    radio: '请选择',
    textarea: '请输入',
    upload: '请上传',
  };

  let uploadTest = null;

  // const setting = settings()
  const { fileList, beforeAppendUpload, initFileUpload } = {};
  // 获取后缀名
  function getSuffix(item) {
    return 'zip';
  }
  const beforeFileUpload = (file: any, item: any) => {
    console.log('be-------', file.name);
    const arr = file.name.split('.');
    const upType = arr[arr.length - 1].toLocaleLowerCase();

    if (item.limit && formData.value[`${item.field}`].length >= item.limit) {
      ElMessage({
        type: 'error',
        message: '超过最大上传数量',
      });
      return false;
    }
    if (!item.accept.includes(upType)) {
      ElMessage({
        type: 'error',
        message: '上传文件类型不正确',
      });
      return false;
    }
    const isLimitFile = true;
    uploadTest = file;
    console.log(uploadTest);
    console.log('beforeFileUpload', item);
    formData.value[`${item.field}_loading`] = true;

    return isLimitFile;
  };
  // 上传
  const imgUrl = '';
  const uploadSuccess = (url: string, request: any, index, item) => {
    console.log('上传成功', `${url}`);
    console.log('上传成功request', request);
    formData.value[`${item.field}`].push({
      name: imgUrl + request.file.name,
      url,
    });

    formData.value[`${item.field}_loading`] = false;
    delete formData.value[`${item.field}_loading`];
    console.log('222', formData, item);
  };
  const removeFile = (item, upIndex) => {
    console.log('del', item.field, formData.value[`${item.field}`]);
    formData.value[`${item.field}`].splice(upIndex, 1);

    uploadDom.value[+item.index].clearFiles();
  };
  const uploadDom: any = ref(null);

  function abortUpload(item) {
    // 取消上传
    const index = +item.index;
    console.log(111, uploadDom.value[index]);
    console.log(222, uploadDom.value[index].abort);

    uploadDom.value[index].abort();
    uploadDom.value[index].clearFiles();

    formData.value[`${item.field}_loading`] = false;
    formData.value.percent = 0;
    removeFile(item);
  }
  function uploadFileError(error) {
    console.log('error！', error);
  }
  function uploadFileNext(next, item) {
    // 上传文件进度
    const percent = parseInt(next.total.percent.toFixed(0));
    // console.log(percent, item);
    item.percent = percent;
  }
  function uploadClick(item, fItem) {
    downloadFile(item.url, item.name);
  }
  function cancelUploadCallback() {
    console.log('取消');
  }

  // 处理数字输入，允许小数点
  function handleNumberInput(value: string, field: string) {
    // 只允许数字和小数点
    const filteredValue = value.replace(/[^\d.]/g, '');

    // 确保只有一个小数点
    const parts = filteredValue.split('.');
    if (parts.length > 2) {
      const newValue = `${parts[0]}.${parts.slice(1).join('')}`;
      formData.value[field] = newValue;
    } else {
      formData.value[field] = filteredValue;
    }
  }
  function inits() {
    (props.option.formList || []).forEach((item) => {
      formData.value[item.field] = item.val;
      if (item.type == 'upload') {
        formData.value[`${item.field}_loading`] = false;
      }
      if (item.rules && item.rules.length > 0) {
        console.log('自带');
        rules[item.field] = item.rules;
      } else if (item.require) {
        console.log('默认');
        rules[item.field] = {
          required: true,
          message: `${errorTips[item.type] || '请填写'}${
            item.error || item.label
          }`,
          trigger: ['blur'],
        };
      } else {
        rules[item.field] = [];
      }

      setTimeout(() => {
        formDom.value.clearValidate([item.field]); // 初始清除校验
      }, 0);
    });
  }
  defineExpose({ ResetFormDate, submit });
  onMounted(() => {
    inits();
  });
</script>

<style lang="less" scoped>
  .page {
  }
  .uploadHeight {
    // height: 192px;
  }
  .btn-foot {
    width: 100%;
    display: flex;
    justify-content: flex-end;
  }

  .row-box {
    overflow: hidden;
    // min-height: 200px;
    display: flex;
    flex-wrap: wrap;
  }
  .between {
    justify-content: space-between;
  }

  .row-one {
    width: calc(50% - 15px);
    float: left;
  }

  .rightMargin {
    margin-right: 20px;
  }

  .upload-box {
    // width: 50%;
    // height: 102px;
    // border: 1px solid;
  }

  // 天杀的ui，设计这玩意布局，
  .selectLine {
    position: relative;
    left: calc(-50%);
    top: 80px;
    width: 0;

    & > div {
      width: 445px;
    }
  }

  .annexUpLoad {
    :deep(.el-upload) {
      width: 100%;
    }
  }
  .up-list-box {
    display: flex;
    align-items: center;
    width: 100%;

    .file-icon {
      width: 16px;
      height: 16px;
      margin-right: 5px;
    }

    .upload-btn-it {
      margin-left: 10px;
      color: #112170;
    }

    .up-name {
      line-height: 20px;
      width: calc(100% - 138px);
      // width: 67%;
      display: flex;
      align-items: center;
    }
  }
  //todo - 缺少css  引入中
  .upload-box {
    // width: 100px;
    // height: 100px;
    // border-radius: 4px;
    // border: 1px solid rgb(220, 223, 230);
    // margin-right: 10px;

    // display: flex;
    // align-items: center;
    // flex-direction: column;
    // justify-content: center;
    .upload-name {
      width: 100%;
      padding: 0 5%;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      min-height: 32px;
      font-size: 12px;
      color: #a8abb2;
    }
    .show-img {
      width: 60%;
      margin: -15px auto 0;
      display: block;
    }
    .show-type-img {
      width: 100%;
      height: 100%;
      border-radius: 4px;
      position: absolute;
    }
    .h5-del {
      width: 30px;
      height: 30px;
      position: absolute;
      top: 0;
      right: 0;
      display: flex;
      align-items: center;
      justify-content: center;
    }
  }
  .h5UploadBoc {
    width: 28.5vw;
    height: 28vw;
    overflow: hidden;
    margin-bottom: 10px;
  }
  .videoBox {
    width: calc(100vw - 30px);
    height: 220px;
    // border: 1px solid red;
    margin-right: 0;
    overflow: hidden;
    text-align: center;
    background-color: rgba(0, 0, 0, 0.1);

    .video-file {
      object-fit: fill;
      width: auto;
      height: 220px;
      object-position: center;
    }
  }

  .download-btn {
    min-width: 100px;
    height: 32px;
    text-align: center;
    line-height: 32px;
    border-radius: 4px;
    color: #112170;
    border: 1px solid #dcdee0;
    cursor: pointer;
    margin-left: 20px;
    margin-top: 30px;
    font-weight: 500;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 10px;

    span {
      margin-left: 5px;
    }
  }

  .download-btn:hover {
    opacity: 0.5;
  }

  .remove-img {
    position: absolute;
    top: 35%;
    left: 42%;
  }
  .hover-box:hover .del-box {
    display: block;
  }
  .hover-box {
    height: 100%;
  }
  .del-box {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    background: rgba(0, 0, 0, 0.5);
    border-radius: 4px;
    display: none;
  }
  .wps-edit-btn {
    position: absolute;
    left: 126px;
    top: 72px;
    color: #112170;
    cursor: pointer;
    width: 100px;
  }
  .wps-edit:hover {
    opacity: 0.5;
  }
  .wps-edit-box {
    position: absolute;
    right: 10px;
    top: 10px;
    color: #112170;
    cursor: pointer;
  }

  .self-box {
    position: relative;
    width: 100%;

    .preview-banner {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
  }

  .color-font {
    color: #999999;
  }

  .row2-line {
    display: flex;
    flex-wrap: wrap;
    flex-direction: row;
    width: 100%;

    .default-img {
      display: block;
      width: 40px;
      margin: 28px auto;
    }
    .mini-img {
      width: 30px;
    }

    .upload-btn {
      margin-left: 20px;
    }
  }

  .btn-list {
    display: flex;
    justify-content: center;
    margin-top: 15px;
  }
  .upload-width {
    width: 100%;
  }
  .progress {
    display: flex;
    .progress-num {
      width: 80%;
    }
  }
  .uploadRow {
    :deep(.el-form-item__error) {
      // top: 91%;
    }
  }
  .up-accept {
    color: #a8abb2;
    font-size: 12px;
  }
  .title-box {
    position: relative;
    width: calc(100% + 100px);
    border-bottom: 1px solid #dcdfe6;
    margin: 10px 0;
    margin-left: -100px;
  }

  .labelH5 {
    :deep(.el-form-item__label) {
      line-height: 18px;
    }
  }
</style>

<style>
  .is-disabled .el-select__placeholder {
    color: #a8abb2 !important;
  }
</style>
